#pragma once

#include <string>
#include <map>
#include <mutex>
#include <memory>
#include <functional>

namespace El {
namespace Common {

/**
 * @brief 公共属性管理类
 */
class CommonProperty {
public:
    /**
     * @brief 属性值获取回调函数类型定义
     * @return 属性值(字符串类型)
     */
    using PropertyCallback = std::function<std::string()>;

    /**
     * @brief 获取单例实例
     * @return CommonProperty实例的引用
     */
    static CommonProperty &GetInstance();

    /**
     * @brief 注册属性回调函数
     * @param key 属性键名
     * @param callback 回调函数
     */
    void RegisterCallback(const std::string &key, PropertyCallback callback);

    /**
     * @brief 注销属性回调函数
     * @param key 属性键名
     */
    void UnregisterCallback(const std::string &key);

    /**
     * @brief 设置属性值
     * @param key 属性键名
     * @param value 属性值(字符串类型)
     */
    void SetProperty(const std::string &key, const std::string &value);

    /**
     * @brief 获取属性值
     * @param key 属性键名
     * @param defaultValue 默认值，当键名不存在且没有回调函数时返回
     * @return 属性值(字符串类型)
     */
    std::string GetProperty(const std::string &key, const std::string &defaultValue = "") const;

    /**
     * @brief 设置属性值
     * @param key 属性键名
     * @param value 属性值(整数类型)
     */
    void SetProperty(const std::string &key, int32_t value);

    /**
     * @brief 获取属性值
     * @param key 属性键名
     * @param defaultValue 默认值，当键名不存在且没有回调函数时返回
     * @return 属性值(整数类型)
     */
    int32_t GetProperty(const std::string &key, int32_t defaultValue = 0) const;

    /**
     * @brief 检查属性是否存在
     * @param key 属性键名
     * @return 如果属性存在或有回调函数返回true，否则返回false
     */
    bool HasProperty(const std::string &key) const;

    /**
     * @brief 删除属性
     * @param key 要删除的属性键名
     */
    void RemoveProperty(const std::string &key);

    /**
     * @brief 清除所有属性和回调函数
     */
    void Clear();

private:
    CommonProperty() = default;
    ~CommonProperty() = default;
    CommonProperty(const CommonProperty &) = delete;
    CommonProperty &operator=(const CommonProperty &) = delete;

private:
    mutable std::mutex mutex_;
    std::map<std::string, std::string> properties_;
    std::map<std::string, PropertyCallback> callbacks_;
};

} // namespace common
} // namespace El
